/*
 * Angry Monsters, Windows Mobile 7 XNA Game FW demo
 * Tero Paananen, tepaanan@gmail.com
 * 2011 Finland
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input.Touch;


// http://box2dxna.codeplex.com
using Box2D.XNA;

namespace WP7Box2d
{

    /* MyContactListener **********************************************************
     * */
    class MyContactListener : Box2D.XNA.IContactListener
    {
        // Hit event
        public event EventHandler Hit;
        
        public void BeginContact(Contact contact)
        {
            Body bodyA = contact.GetFixtureA().GetBody();
            CustomUserData cudA = (CustomUserData)bodyA.GetUserData();

            Body bodyB = contact.GetFixtureB().GetBody();
            CustomUserData cudB = (CustomUserData)bodyB.GetUserData();

            if (cudA != null && cudB != null)
            {
                if (cudA.m_type == CustomUserData.UserDataType.EEnemy &&
                    cudB.m_type == CustomUserData.UserDataType.EAmmon)
                {
                    // Send GameOver even
                    if (Hit != null)
                    {
                        cudA.m_hit = true;
                        Hit(this, new EventArgs());
                    }
                }
            }
        }
        
        public void EndContact(Contact contact)
        {
        }
        
        public void PreSolve(Contact contact, ref Manifold oldManifold)
        {
        }
        
        public void PostSolve(Contact contact, ref ContactImpulse impulse)
        {
        }
    }


    /* CustomUserData ************************************************************
     * */
    class CustomUserData
    {
        public enum UserDataType
        {
            ENoType = 0,
            EEnemy = 1,
            EAmmon = 2,
            EBlock = 3
        }

        public Texture2D m_texture = null;
        public UserDataType m_type = UserDataType.ENoType;

        public bool m_hit = false;
        public int m_hitCount = 50;

        public bool m_visible = true;

        public CustomUserData(Texture2D texture, UserDataType type)
        {
            m_texture = texture;
            m_type = type;
        }

        public Texture2D Texture()
        {
            return m_texture;
        }

    }
    
    
    /* BoxHandler *****************************************************************
     * */
    class BoxHandler
    {
        //float m_timeStep = 1.0f / 30.0f; // 30 times in second
        float m_timeStep = 1.0f / 60.0f; // 60 times in second
        Int32 m_velocityIterations = 10;//6;
        Int32 m_positionIterations = 10;//2;

        public World m_world = null;
        private MyContactListener m_contactListener = null;

        public List<Body> m_boxBodylist = new List<Body>();
        public List<Body> m_boxEnemyBodylist = new List<Body>();

        // value 10 : 10 meters in Box2D is 100 pixels
        // value 20 : 5 meters in Box2D is 100 pixels
        // value 30 : 3 meters in Box2D is 100 pixels
        public float pixelsFromMeters = 30;

        public Texture2D m_splashtexture = null;

        public Texture2D m_Groundtexture = null;
        public Rectangle m_groundRec;

        public Texture2D m_angryTexture = null;
        public Texture2D m_monstersTexture = null;

        public Texture2D m_catapult = null;

        public Texture2D m_hitTexture = null;

        public Texture2D m_skyTexture = null;
        public Texture2D m_ammon = null;
        private Body m_ammonBody;
        public Texture2D m_pen = null;


        public Texture2D m_box1 = null; // Box 40x40
        public Texture2D m_box2l = null;   // Box 80x40
        public Texture2D m_box2p = null;   // Box 40x80
        public Texture2D m_box3l = null;   // Box 120x40
        public Texture2D m_box3p = null;   // Box 40x120
        public Texture2D m_box4l = null;   // Box 160x40
        public Texture2D m_box4p = null;   // Box 40x160

        public Texture2D m_enemy1 = null;
        public Texture2D m_enemy2 = null;
        public Texture2D m_enemy3 = null;

        public Random m_random = new Random();

        public Vector2 m_catapultPos;

        public Vector2 m_size;

        private ContentManager m_cm;

        private Audio m_audio = null;

        public delegate void GameOverEvent();
        public event GameOverEvent GameOverHitEvent;

        public BoxHandler(ContentManager cm)
        {
            m_cm = cm;
        }

        public void SetAudio(Audio a)
        {
            m_audio = a;
        }



        void HitEventHanlder(object sender, EventArgs e)
        {
            // Hit event comes here
            System.Diagnostics.Debug.WriteLine("Hit!");

            if (m_audio != null)
            {
                m_audio.PlayArgh();
                m_audio.PlayHit();
            }
        }

        void GameOver()
        {
            // Game over event comes here
            System.Diagnostics.Debug.WriteLine("Game Over!");
            GameOverHitEvent();
        }
        
        public Texture2D GetLevelItemTexture(LevelEditorItem.EditorItemType type)
        {
            Texture2D ret = null;
            switch (type)
            {
                case LevelEditorItem.EditorItemType.EBox1:
                    {
                        ret = m_box1;
                        break;
                    }
                case LevelEditorItem.EditorItemType.EBox2l:
                    {
                        ret = m_box2l;
                        break;
                    }
                case LevelEditorItem.EditorItemType.EBox2p:
                    {
                        ret = m_box2p;
                        break;
                    }
                case LevelEditorItem.EditorItemType.EBox3l:
                    {
                        ret = m_box3l;
                        break;
                    }
                case LevelEditorItem.EditorItemType.EBox3p:
                    {
                        ret = m_box3p;
                        break;
                    }
                case LevelEditorItem.EditorItemType.EBox4l:
                    {
                        ret = m_box4l;
                        break;
                    }
                case LevelEditorItem.EditorItemType.EBox4p:
                    {
                        ret = m_box4p;
                        break;
                    }
                case LevelEditorItem.EditorItemType.EEnemy1:
                    {
                        ret = m_enemy1;
                        break;
                    }
                case LevelEditorItem.EditorItemType.EEnemy2:
                    {
                        ret = m_enemy2;
                        break;
                    }
                case LevelEditorItem.EditorItemType.EEnemy3:
                    {
                        ret = m_enemy3;
                        break;
                    }
            }
            return ret;
        }

        public void CreateWorld(Vector2 size)
        {
            m_size = size;

            // Box2D World
            m_world = new World(new Vector2(0.0f, 10.0f), true); // -10 is gravity

            // Contact listenter (collision)
            if (m_contactListener == null)
            {
                // Hit event
                m_contactListener = new MyContactListener();
                m_contactListener.Hit += new EventHandler(HitEventHanlder);
            }
            m_world.ContactListener = m_contactListener;
            
            // Box2D Ground
            BodyDef bodyDef = new BodyDef();
            // NOTE: position is center of item
            bodyDef.position = new Vector2((size.X / 2.0f) / pixelsFromMeters,
                (size.Y - 5.0f) / pixelsFromMeters);
            Body groundBody = m_world.CreateBody(bodyDef);
            PolygonShape groundBox = new PolygonShape();
            // NOTE: use radius width in SetAsBox
            groundBox.SetAsBox((size.X / pixelsFromMeters) / 2, (20.0f / pixelsFromMeters) / 2);
            groundBody.CreateFixture(groundBox, 0);

            // Box2D Ground ++
            Body groundBody2 = m_world.CreateBody(bodyDef);
            PolygonShape groundBox2 = new PolygonShape();
            // NOTE: use radius width in SetAsBox
            groundBox2.SetAsBox((size.X / pixelsFromMeters) * 2, (20.0f / pixelsFromMeters) / 2);
            groundBody2.CreateFixture(groundBox2, 0);

            // Left wall
            BodyDef leftWallbodyDef = new BodyDef();
            // NOTE: position is center of item
            leftWallbodyDef.position = new Vector2((10.0f / 2.0f) / pixelsFromMeters,
                (size.Y / 2.0f) / pixelsFromMeters);
            Body leftWallBody = m_world.CreateBody(leftWallbodyDef);
            PolygonShape leftWallBox = new PolygonShape();
            // NOTE: use radius width in SetAsBox
            leftWallBox.SetAsBox((10.0f / pixelsFromMeters) / 2, 
                (size.Y / pixelsFromMeters) / 2);
            leftWallBody.CreateFixture(leftWallBox, 0);

            // Right wall
            BodyDef rightWallbodyDef = new BodyDef();
            // NOTE: position is center of item
            rightWallbodyDef.position = new Vector2(((10.0f / 2.0f) / pixelsFromMeters) + ((size.X / pixelsFromMeters) * 2),
                (size.Y / 2.0f) / pixelsFromMeters);
            Body rightWallBody = m_world.CreateBody(rightWallbodyDef);
            PolygonShape rightWallBox = new PolygonShape();
            // NOTE: use radius width in SetAsBox
            rightWallBox.SetAsBox((10.0f / pixelsFromMeters) / 2,
                (size.Y / pixelsFromMeters) / 2);
            rightWallBody.CreateFixture(rightWallBox, 0);


            // Top/sky wall
            BodyDef skyWallbodyDef = new BodyDef();
            // NOTE: position is center of item
            skyWallbodyDef.position = new Vector2((size.X / 2.0f) / pixelsFromMeters,
                (10.0f / 2.0f) / pixelsFromMeters);
            Body skyWallBody = m_world.CreateBody(skyWallbodyDef);
            PolygonShape skyBox = new PolygonShape();
            // NOTE: use radius width in SetAsBox
            skyBox.SetAsBox((size.X / pixelsFromMeters) / 2, (10.0f / pixelsFromMeters) / 2);
            skyWallBody.CreateFixture(skyBox, 0);

            // Top/sky wall ++
            Body skyWallBody2 = m_world.CreateBody(skyWallbodyDef);
            PolygonShape skyBox2 = new PolygonShape();
            // NOTE: use radius width in SetAsBox
            skyBox2.SetAsBox((size.X / pixelsFromMeters) * 2, (10.0f / pixelsFromMeters) / 2);
            skyWallBody2.CreateFixture(skyBox2, 0);


            // Ground texture top left corner
            m_groundRec = new Rectangle(0, 460, (int)size.X, 25);
        }

        public void ClearBoxWorld()
        {
            m_world.ClearForces();
            for (int i = 0; i < m_boxBodylist.Count(); i++)
            {
                Body b = m_boxBodylist[i];
                m_world.DestroyBody(b);
                m_boxBodylist.RemoveAt(i);
                b = null;
                i--;
            }

            for (int i = 0; i < m_boxEnemyBodylist.Count(); i++)
            {
                Body b = m_boxEnemyBodylist[i];
                m_world.DestroyBody(b);
                m_boxEnemyBodylist.RemoveAt(i);
                b = null;
                i--;
            }

        }

        public void LoadSplashScreenContent(ContentManager theContentManager)
        {
            m_splashtexture = theContentManager.Load<Texture2D>("splashscreen");
            m_pen = theContentManager.Load<Texture2D>("kyna");
            m_skyTexture = theContentManager.Load<Texture2D>("grid");
        }

        public void LoadContent()
        {
            LoadContent(m_cm);
        }

        private void LoadContent(ContentManager theContentManager)
        {
            if (m_box1 == null)
            {
                m_box1 = theContentManager.Load<Texture2D>("tile3");

                m_box2l = theContentManager.Load<Texture2D>("laatikko-2");
                m_box2p = theContentManager.Load<Texture2D>("laatikko-2b");

                m_box3l = theContentManager.Load<Texture2D>("laatikko-3");
                m_box3p = theContentManager.Load<Texture2D>("laatikko-3b");

                m_box4l = theContentManager.Load<Texture2D>("laatikko-4");
                m_box4p = theContentManager.Load<Texture2D>("laatikko-4b");

                m_enemy1 = theContentManager.Load<Texture2D>("enemy1");
                m_enemy2 = theContentManager.Load<Texture2D>("enemy2");
                m_enemy3 = theContentManager.Load<Texture2D>("enemy3b");

                m_Groundtexture = theContentManager.Load<Texture2D>("ground");
                m_ammon = theContentManager.Load<Texture2D>("rock");

                m_angryTexture = theContentManager.Load<Texture2D>("angry2");
                m_monstersTexture = theContentManager.Load<Texture2D>("monsters2");

                m_hitTexture = theContentManager.Load<Texture2D>("bumm");
            }
        }

        public void CreateCatapult()
        {
            m_catapult = m_cm.Load<Texture2D>("ritsa");

            m_catapultPos.Y = 480 - m_catapult.Height + 50;
            m_catapultPos.X = m_catapult.Width;

            // Box2D Catapult
            BodyDef bodyDef = new BodyDef();
            // NOTE: position is center of item
            bodyDef.position = new Vector2(((m_catapult.Width * 2.5f) / 2.0f) / pixelsFromMeters, 
                (480 - (m_catapult.Height / 2.0f) + 100) / pixelsFromMeters);
            Body catBody = m_world.CreateBody(bodyDef);
            PolygonShape catBox = new PolygonShape();
            // NOTE: use radius width in SetAsBox
            catBox.SetAsBox((m_catapult.Width * 0.5f / pixelsFromMeters) / 2, (m_catapult.Height / pixelsFromMeters) / 2);
            catBody.CreateFixture(catBox, 0);

        }

        public void DrawSplashScreen(SpriteBatch spriteBatch, float cameraOffset)
        {
            spriteBatch.Draw(m_splashtexture, new Rectangle(0, 0, 800, 480), Color.White);

            spriteBatch.Draw(m_pen, new Rectangle(700, 300, m_pen.Width, m_pen.Height), Color.White);
        }

        public void DrawSky(SpriteBatch spriteBatch)
        {
            // Sky
            spriteBatch.Draw(m_skyTexture, new Rectangle(0, 0, 800, 480), Color.White);
        }

        public void DrawSkyAndGround(SpriteBatch spriteBatch, float cameraOffset)
        {
            // Sky
            spriteBatch.Draw(m_skyTexture, new Rectangle(0, 0, 800, 480), Color.White);

            // Ground
            Vector2 cPos = new Vector2(m_groundRec.X, m_groundRec.Y);
            cPos.X = cPos.X - (int)cameraOffset;
            spriteBatch.Draw(m_Groundtexture, cPos, Color.White);
            cPos.X = cPos.X + m_Groundtexture.Width - 10;
            spriteBatch.Draw(m_Groundtexture, cPos, Color.White);

            // Catapult
            cPos = new Vector2(m_catapultPos.X, m_catapultPos.Y);
            cPos.X -= (int)cameraOffset;
            spriteBatch.Draw(m_catapult, cPos, Color.White);

        }

        public void DrawWorld(SpriteBatch spriteBatch, float cameraOffset)
        {
            // Sky
            spriteBatch.Draw(m_skyTexture, new Rectangle(0, 0, 800, 480), Color.White);

            // Ground
            Vector2 cPos = new Vector2(m_groundRec.X, m_groundRec.Y);
            cPos.X -= (int)cameraOffset;
            spriteBatch.Draw(m_Groundtexture, cPos, Color.White);
            cPos.X += m_Groundtexture.Width-10;
            spriteBatch.Draw(m_Groundtexture, cPos, Color.White);

            // Catapult
            cPos = new Vector2(m_catapultPos.X, m_catapultPos.Y);
            cPos.X -= (int)cameraOffset;
            spriteBatch.Draw(m_catapult, cPos, Color.White);

            // Logo
            spriteBatch.Draw(m_angryTexture, new Rectangle(5, 5, m_angryTexture.Width, m_angryTexture.Height), Color.White);
            spriteBatch.Draw(m_monstersTexture, new Rectangle(5, m_angryTexture.Height+10, m_monstersTexture.Width, m_monstersTexture.Height), Color.White);
        
            // Pen
            spriteBatch.Draw(m_pen, new Rectangle((800 + 800) - (int)cameraOffset, 50, m_pen.Width, m_pen.Height), Color.White);
        }

        public void DeleteAmmon()
        {
            m_world.ClearForces();
            for (int i = 0; i < m_boxBodylist.Count(); i++)
            {
                Body b = m_boxBodylist[i];
                if (b.IsBullet)
                {
                    m_world.DestroyBody(b);
                    m_boxBodylist.RemoveAt(i);
                    m_ammonBody = null;
                    break;
                }
            }
        }

        public Body CreateAmmon()
        {
            // Create Box2D object
            BodyDef bodyDef2 = new BodyDef();
            bodyDef2.type = BodyType.Dynamic;
            bodyDef2.allowSleep = true;
            bodyDef2.bullet = true; // Note: bullet
            bodyDef2.position = new Vector2((m_catapult.Width * 1.5f) / pixelsFromMeters,
                (m_catapultPos.Y) / pixelsFromMeters);

            m_ammonBody = m_world.CreateBody(bodyDef2);

            CircleShape circle = new CircleShape();
            circle._radius = 0.5f;

            // TODO: check these values
            FixtureDef fixtureDef = new FixtureDef();
            fixtureDef.shape = circle;
            fixtureDef.density = 3.0f;      // tiheys
            fixtureDef.friction = 0.5f;     // kitka
            fixtureDef.restitution = 0.2f;  // kimmosuus

            m_ammonBody.CreateFixture(fixtureDef);
            m_ammonBody.SetUserData(new CustomUserData(m_ammon, CustomUserData.UserDataType.EAmmon));

            m_boxBodylist.Add(m_ammonBody);
            return m_ammonBody;
        }

        public Body CreateEnemy(int type, Vector2 toPosition)
        {
            // Create Box2D object
            BodyDef bodyDef2 = new BodyDef();
            bodyDef2.type = BodyType.Dynamic; // TODO: No need to be Dynamic?
            bodyDef2.allowSleep = true;
            // NOTE: position is center of item
            bodyDef2.position = new Vector2(toPosition.X / pixelsFromMeters, toPosition.Y / pixelsFromMeters);
            Body body = m_world.CreateBody(bodyDef2);
            PolygonShape dynamicBox = new PolygonShape();

            // Select right texture from different boxes
            Texture2D usedTexture = null;
            switch (type)
            {
                case 1:
                    {
                        usedTexture = m_enemy1;
                        break;
                    }
                case 2:
                    {
                        usedTexture = m_enemy2;
                        break;
                    }
                case 3:
                    {
                        usedTexture = m_enemy3;
                        break;
                    }
            }
            body.SetUserData(new CustomUserData(usedTexture, CustomUserData.UserDataType.EEnemy));


            // NOTE: use radius width in SetAsBox
            dynamicBox.SetAsBox((usedTexture.Width / pixelsFromMeters) / 2, (usedTexture.Height / pixelsFromMeters) / 2);
            FixtureDef fixtureDef = new FixtureDef();
            fixtureDef.shape = dynamicBox;
            // TODO: Check these values
            fixtureDef.density = 2.0f; // tiheys
            fixtureDef.friction = 1.0f; // kitka
            fixtureDef.restitution = 0.1f; // kimmosuus

            body.CreateFixture(fixtureDef);

            //m_boxBodylist.Add(body);
            m_boxEnemyBodylist.Add(body);

            return body;
        }

        public Body CreateBoxBody(int boxType, bool portrait, Vector2 toPosition)
        {
            // Create Box2D object
            BodyDef bodyDef2 = new BodyDef();
            bodyDef2.type = BodyType.Dynamic;
            bodyDef2.allowSleep = true;
            // NOTE: position is center of item
            bodyDef2.position = new Vector2(toPosition.X / pixelsFromMeters, toPosition.Y / pixelsFromMeters);
            Body body = m_world.CreateBody(bodyDef2);
            //body.ApplyTorque(m_random.Next(-10, 10)); // TODO: This is not needed?
            PolygonShape dynamicBox = new PolygonShape();

            // Select right texture from different boxes
            Texture2D usedTexture = null;
            FixtureDef fixtureDef = new FixtureDef();
            fixtureDef.shape = dynamicBox;

            switch (boxType)
            {
                case 1:
                    {
                        usedTexture = m_box1;

                        fixtureDef.density = 1.0f; // tiheys
                        fixtureDef.friction = 1.0f; // kitka
                        fixtureDef.restitution = 0.1f; // kimmosuus
                        break;
                    }
                case 2:
                    {
                        if (portrait)
                            usedTexture = m_box2p;
                        else
                            usedTexture = m_box2l;

                        fixtureDef.density = 0.5f; // tiheys
                        fixtureDef.friction = 1.0f; // kitka
                        fixtureDef.restitution = 0.1f; // kimmosuus
                        break;
                    }
                case 3:
                    {
                        if (portrait)
                            usedTexture = m_box3p;
                        else
                            usedTexture = m_box3l;

                        fixtureDef.density = 0.5f; // tiheys
                        fixtureDef.friction = 1.0f; // kitka
                        fixtureDef.restitution = 0.1f; // kimmosuus
                        break;
                    }
                case 4:
                    {
                        if (portrait)
                            usedTexture = m_box4p;
                        else
                            usedTexture = m_box4l;

                        fixtureDef.density = 0.5f; // tiheys
                        fixtureDef.friction = 1.0f; // kitka
                        fixtureDef.restitution = 0.1f; // kimmosuus
                        break;
                    }
            }
            body.SetUserData(new CustomUserData(usedTexture, CustomUserData.UserDataType.EBlock));

            //System.Diagnostics.Debug.WriteLine(usedTexture.Width);
            //System.Diagnostics.Debug.WriteLine(usedTexture.Height);

            // NOTE: use radius width in SetAsBox
            dynamicBox.SetAsBox((usedTexture.Width / pixelsFromMeters) / 2, (usedTexture.Height / pixelsFromMeters) / 2);

            body.CreateFixture(fixtureDef);

            m_boxBodylist.Add(body);

            return body;
        }

        public void DrawEnemyBoxList(SpriteBatch spriteBatch, float cameraOffset)
        {
            // Box2D Enemies Items
            for (int i = 0; i < m_boxEnemyBodylist.Count(); i++)
            {
                Body b = m_boxEnemyBodylist[i];

                // Change Box2D position in meters to position in pixels
                Vector2 p = b.GetPosition();
                p.X = p.X * pixelsFromMeters;
                p.Y = p.Y * pixelsFromMeters;

                Vector2 drawPos = p;
                drawPos.X = drawPos.X - cameraOffset;

                Texture2D texture;

                // Draw
                CustomUserData cud = (CustomUserData)b.GetUserData();
                if (cud != null && cud.Texture() != null && cud.m_visible)
                {
                    texture = cud.Texture();
                    spriteBatch.Draw(texture,
                        drawPos,
                        null,
                        Color.White,
                        b.GetAngle(),
                        new Vector2(texture.Width * 0.5f, texture.Height * 0.5f),
                        1.0f,
                        SpriteEffects.None,
                        0.0f);

                    // Draw hit about 1.5 sec
                    if (cud.m_hit && cud.m_hitCount > 0)
                    {
                        cud.m_hitCount--;
                        drawPos.Y = drawPos.Y - texture.Height * 0.5f;
                        texture = m_hitTexture;
                        spriteBatch.Draw(texture,
                            drawPos,
                            null,
                            Color.White,
                            0,
                            new Vector2(texture.Width * 0.5f, texture.Height * 0.5f),
                            (float)m_random.NextDouble() * 1.5f,
                            SpriteEffects.None,
                            0.0f);

                        // Hit drawed
                        if (cud.m_hitCount == 0)
                        {
                            cud.m_visible = false;
                            m_boxEnemyBodylist.RemoveAt(i);
                            m_world.DestroyBody(b);
                            b = null;
                            i--;

                            // Is there enemies left?
                            if (m_boxEnemyBodylist.Count() < 1)
                            {
                                GameOver();
                            }
                        }

                    }
                }

            }

        }


        public void DrawBoxList(SpriteBatch spriteBatch, float cameraOffset)
        {
            // Box2D Items
            for (int i = 0; i < m_boxBodylist.Count(); i++)
            {
                Body b = m_boxBodylist[i];

                // Change Box2D position in meters to position in pixels
                Vector2 p = b.GetPosition();
                p.X = p.X * pixelsFromMeters;
                p.Y = p.Y * pixelsFromMeters;

                Vector2 drawPos = p;
                drawPos.X = drawPos.X - cameraOffset;

                // Draw
                CustomUserData cud = (CustomUserData)b.GetUserData();
                if (cud != null && cud.Texture() != null && cud.m_visible)
                {
                    Texture2D texture = cud.Texture();
                    spriteBatch.Draw(texture,
                        drawPos,
                        null,
                        Color.White,
                        b.GetAngle(),
                        new Vector2(texture.Width * 0.5f, texture.Height * 0.5f),
                        1.0f,
                        SpriteEffects.None,
                        0.0f);
                }
            }
        }
        

        public bool isAmmonBodyTouched(ref Body touchedBody, Vector2 pos)
        {
            for (int i = 0; i < m_boxBodylist.Count(); i++)
            {
                // Find ammon body
                Body body = m_boxBodylist[i];
                if (!body.IsBullet)
                    continue;

                Vector2 p = body.GetPosition();
                p.X = p.X * pixelsFromMeters;
                p.Y = p.Y * pixelsFromMeters;

                CustomUserData cud = (CustomUserData)body.GetUserData();
                Texture2D texture = cud.Texture();
                int textureWidth = texture.Width;

                // Make touch area bigger
                Rectangle r = new Rectangle((int)p.X - textureWidth,
                    (int)p.Y - textureWidth,
                    textureWidth*2, textureWidth*2);
                if (r.Contains(new Microsoft.Xna.Framework.Point((int)pos.X, (int)pos.Y)))
                {
                    touchedBody = body;
                    return true;
                }
            }
            return false;
        }

        public void Update(GameTime gameTime)
        {
            // Next step in Box2D
            m_world.Step(m_timeStep, m_velocityIterations, m_positionIterations);
            m_world.ClearForces();
        }


    }
}
